using Cysharp.Threading.Tasks;
using IQIGame.Onigao.Framework;
using IQIGame.Onigao.Game;
using System.Collections.Generic;
using UnityEngine;

namespace IQIGame.Onigao.GamePlay
{
    public class UIEquipList : UIBaseWindow
    {
        /// <summary>
        /// 静态配置
        /// </summary>
        private static UICreateConfig _createConfig = new()
        {
            prefabName = nameof(UIEquipList),
            layer = EUILayer.Normal,
            isFullScreen = true,
        };

        /// <summary>
        /// 创建UI的配置
        /// </summary>
        public override IUICreateConfig createConfig => _createConfig;

        #region Template Generate,don't modify
        protected partial class UIB_UIEquipList
        {
            #region ObjectBinding Generate
            public GameObject topLeftBack { protected set; get; }
            public UnityEngine.UI.ExLoopVerticalScrollRect loopScrollRect { protected set; get; }
            public GameObject empty { protected set; get; }
            public IQIGame.Onigao.Framework.ExText textNum { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton btnSort { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton btnSetting { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton btnFilter { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton btnFilterClear { protected set; get; }
            public GameObject buttonGroupOpt { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton btnDecompose { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton btnLock { protected set; get; }
            public GameObject decomposeState { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton btnCancelDecompose { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton btnExcuteDecompose { protected set; get; }
            public GameObject toggleQuickSelected { protected set; get; }
            public virtual void InitBinding(ObjectBinding __binding)
            {
                __binding.TryGetVariableValue<UnityEngine.GameObject>("topLeftBack", out var __tbv0);
                this.topLeftBack = __tbv0;
                __binding.TryGetVariableValue<UnityEngine.UI.ExLoopVerticalScrollRect>("loopScrollRect", out var __tbv1);
                this.loopScrollRect = __tbv1;
                __binding.TryGetVariableValue<UnityEngine.GameObject>("empty", out var __tbv2);
                this.empty = __tbv2;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExText>("textNum", out var __tbv3);
                this.textNum = __tbv3;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExButton>("btnSort", out var __tbv4);
                this.btnSort = __tbv4;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExButton>("btnSetting", out var __tbv5);
                this.btnSetting = __tbv5;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExButton>("btnFilter", out var __tbv6);
                this.btnFilter = __tbv6;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExButton>("btnFilterClear", out var __tbv7);
                this.btnFilterClear = __tbv7;
                __binding.TryGetVariableValue<UnityEngine.GameObject>("buttonGroupOpt", out var __tbv8);
                this.buttonGroupOpt = __tbv8;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExButton>("btnDecompose", out var __tbv9);
                this.btnDecompose = __tbv9;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExButton>("btnLock", out var __tbv10);
                this.btnLock = __tbv10;
                __binding.TryGetVariableValue<UnityEngine.GameObject>("decomposeState", out var __tbv11);
                this.decomposeState = __tbv11;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExButton>("btnCancelDecompose", out var __tbv12);
                this.btnCancelDecompose = __tbv12;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExButton>("btnExcuteDecompose", out var __tbv13);
                this.btnExcuteDecompose = __tbv13;
                __binding.TryGetVariableValue<UnityEngine.GameObject>("toggleQuickSelected", out var __tbv14);
                this.toggleQuickSelected = __tbv14;
            }
            #endregion ObjectBinding Generate 
        }
        #endregion Template Generate,don't modify

        #region fields & properties
        private LoopScrollAdapter<UIN_CommonEquip> loopEquips = null;
        private ListScrollAdapter<UIN_CommonToggle> quickSelecteds = null;

        private List<ItemEquipmentData> dataList = new(8);
        private List<ItemEquipmentData> dataCurrList = new(8);
        private HashSet<long> dataSelected = new(4);
        private UD_EquipList ud => _data as UD_EquipList;

        protected UIB_UIEquipList ui { get; set; }
        private UIMsgDispatcher uiMsgDispatcher => this._msgDispatcher as UIMsgDispatcher;
        #endregion

        protected override void BeforeInit()
        {
            ui = new UIB_UIEquipList();
            ui.InitBinding(this.csObjBind);
        }

        protected override void OnInit()
        {
            this.loopEquips = this.InitLoopScroll<UIN_CommonEquip>(this.ui.loopScrollRect, this.OnEquipChanged);
            this.quickSelecteds = this.InitListScroll<UIN_CommonToggle>(this.ui.toggleQuickSelected, this.OnDecomposeQuickSelectedChanged);

            this.ui.btnFilter.onClick.AddListener(this.OnClickFilter);
            this.ui.btnFilterClear.onClick.AddListener(this.OnClickFilterClear);
            this.ui.btnSort.onClick.AddListener(this.OnClickSort);
            this.ui.btnDecompose.onClick.AddListener(this.OnClick2Decompose);
            this.ui.btnLock.onClick.AddListener(this.OnClickLock);
            this.ui.btnCancelDecompose.onClick.AddListener(this.OnClickCancelDecompose);
            this.ui.btnExcuteDecompose.onClick.AddListener(this.OnClickExcuteDecompose);

            var topLeftBack = this.InitChildNode<UIN_TopLeftBack>(this.ui.topLeftBack);
            topLeftBack.Show();
        }

        protected override void OnShow(UIBaseData data)
        {
            this.View();
        }

        protected override void OnHide()
        {

        }

        protected override UIBaseData OnGetLeaveData()
        {
            UD_EquipList d = UD_EquipList.NewFromPool();
            d.Sync(ud.viewType, ud.filter, ud.sort);
            return d;
        }

        #region 点击函数
        void OnClickFilter()
        {
            this.OpenUI<UIEquipListScreen>(UD_EquipListCreen.Create(this.ud.filter));
        }

        void OnClickFilterClear()
        {
            this.ud.SetDefaultFilter();
            this.Refresh();
        }

        void OnClickSort()
        {
            this.OpenUI<UIEquipListSort>(UD_EquipListSort.Create(this.ud.sort));
        }

        void OnClick2Decompose()
        {
            this.ud.viewType = UIEquipListType.Decompose;
            this.dataSelected.Clear();
            this.ViewBtn();
            this.ViewDecomposeQuickSelect();
            this.RefeshDataList();
        }

        void OnClickCancelDecompose()
        {
            this.ud.viewType = UIEquipListType.None;
            this.dataSelected.Clear();
            this.ViewBtn();
            this.RefeshDataList();
        }

        void OnClickExcuteDecompose()
        {
            if (this.dataSelected.Count == 0)
            {
                NoticeModule.ShowNoticeNoCall(APIUIEquip.NoticeCid_NotHasEquip);
                return;
            }
            var d = UD_UIEquipDecompose.Create().AddRange(dataSelected);
            this.OpenUI<UIEquipDecompose>(d);
        }

        void OnClickLock()
        {
            this.ud.viewType = (this.ud.viewType == UIEquipListType.None) ? UIEquipListType.Lock : UIEquipListType.None;
            this.ViewBtn();
            this.RefeshDataList();
        }
        #endregion

        protected override void OnDispose()
        {
            this.loopEquips = null;
            this.quickSelecteds = null;
            this.ClearDataList();
            this.ClearFitlerDataList();
        }

        #region UIMsgDispatcher
        protected override void AddMsgListeners()
        {
            uiMsgDispatcher.AddListener<EquipSort>(MsgEventType.EquipSort, this.OnMsgEquipSort);
            uiMsgDispatcher.AddListener<EquipFilter>(MsgEventType.EquipFilter, this.OnMsgEquipFilter);
            uiMsgDispatcher.AddListener(MsgEventType.EquipDecomposeSuccess, this.OnMsgEquipDecomposeSuccess);
        }

        void OnMsgEquipSort(EquipSort sort)
        {
            if (this.ud.sort == sort)
                return;
            this.ud.sort = sort;
            this.SortDataList();
            this.ViewDataList();
        }

        void OnMsgEquipFilter(EquipFilter filter)
        {
            if (this.ud.filter == filter)
                return;
            this.ud.filter = filter;
            this.Refresh();
        }

        void OnMsgEquipDecomposeSuccess()
        {
            this.View();
        }
        #endregion

        void View()
        {
            this.ClearDataList();
            this.ClearFitlerDataList();
            this.InitDataList();
            this.Refresh();
        }

        void ClearDataList()
        {
            this.dataList.Clear();
        }

        void InitDataList()
        {
            var list = GameDataCenter.PlayerData.item.GetEquipList();
            this.dataList.AddRange(list);
        }

        void Refresh()
        {
            this.ViewBtn();
            this.FitlerDatalist();
            this.SortDataList();
            this.ViewDataList();

            this.ui.textNum.text = $"{this.dataCurrList.Count}/{this.dataList.Count}";
        }

        void ViewBtn()
        {
            bool isActiveDecomposeState = this.ud.viewType == UIEquipListType.Decompose;
            this.ui.decomposeState.SetActive(isActiveDecomposeState);
            bool isActiveDecompose = this.ud.viewType == UIEquipListType.None;
            this.ui.btnDecompose.SetActive(isActiveDecompose);

            bool isHasFilter = !this.ud.IsFilterDefault;
            this.ui.btnFilter.SetSelectState(isHasFilter);
            this.ui.btnFilterClear.SetActive(isHasFilter);

            bool isLock = this.ud.viewType == UIEquipListType.Lock;
            bool isActiveLock = isLock || this.ud.viewType == UIEquipListType.None;
            this.ui.btnLock.SetActive(isActiveLock);
            if (isActiveLock)
            {
                this.ui.btnLock.SetSelectState(isLock);
                var exText = this.ui.btnLock.tilte;
                if (exText != null)
                {
                    //exText.indexSwitchColor = isLock ? 1 : 0;
                }
            }
        }

        void ClearFitlerDataList()
        {
            this.dataCurrList.Clear();
            this.dataSelected.Clear();
        }

        void FitlerDatalist()
        {
            if (this.ud.viewType != UIEquipListType.Decompose)
                this.dataSelected.Clear();

            this.dataCurrList.Clear();
            this.dataCurrList = ItemModule.Instance.LeachEquipList(this.dataList, this.ud.filter, this.dataCurrList);
        }

        void SortDataList()
        {
            ItemModule.Instance.ReorderEquipList(this.dataCurrList, this.ud.sort);
        }

        void ViewDataList()
        {
            int cnt = this.dataCurrList.Count;
            this.loopEquips.RefillCellsAndSelected(cnt, -1);
            this.ui.empty.SetActive(cnt == 0);
        }

        void RefeshDataList()
        {
            if (this.dataCurrList.Count == 0)
                return;

            this.loopEquips.RefreshCells();
        }

        void OnEquipChanged(UIN_CommonEquip item, int index)
        {
            var data = this.dataCurrList[index];
            bool isLockSelected = this.ud.viewType == UIEquipListType.Lock && data.isLock;
            bool isSelected = this.ud.viewType == UIEquipListType.Decompose && this.dataSelected.Contains(data.id);
            item.Show(data, index);
            item.SetLockSelected(isLockSelected);
            item.SetSelected(isSelected);
            item.SetCallClickSelf(this.OnEquipSelected);
        }

        void OnEquipSelected(int index, UIN_CommonEquip item)
        {
            var data = this.dataCurrList[index];
            if (item == null || data == null)
                return;

            if (this.ud.viewType == UIEquipListType.None)
            {
                UD_EquipInfo udEquip = UD_EquipInfo.NewFromPool();
                udEquip.Sync(UIEquipInfoTabType.Details, data, this.dataCurrList);
                this.OpenUI<UIEquipInfo>(udEquip);
                return;
            }

            bool isLock = data.isLock;
            if (this.ud.viewType == UIEquipListType.Decompose && isLock)
            {
                NoticeModule.ShowNoticeNoCall(APIUIEquip.NoticeCid_LockNotDecompose);
                return;
            }

            if (this.ud.viewType == UIEquipListType.Lock)
            {
                item.SetLockState(!isLock, !isLock);
                this.SendLock(data.id, !isLock, index).Forget();
            }
            else
            {
                bool isSelected = this.dataSelected.Contains(data.id);
                if (isSelected)
                    this.dataSelected.Remove(data.id);
                else
                    this.dataSelected.Add(data.id);
                item.SetSelected(!isSelected);
            }
        }

        void ViewDecomposeQuickSelect()
        {
            this.quickSelecteds.RefillCells(APIUIEquip.DecomposeQuickSelectedTabs.Length);
        }

        void OnDecomposeQuickSelectedChanged(UIN_CommonToggle item, int index)
        {
            string label = APIUIEquip.DecomposeQuickSelectedTabs[index];
            item.SetDefaultIsOn(false);
            item.SetCallOnValChanged(this.OnDecomposeQuickSelectedSelected);
            item.Show(index, label);
        }

        void OnDecomposeQuickSelectedSelected(int index, bool isOn)
        {
            if (this.ud.viewType != UIEquipListType.Decompose)
                return;

            int quality = APIUIEquip.QualityStartValue + index;
            this.RefreshDecomposeQuickSelected(quality, isOn);
        }

        void RefreshDecomposeQuickSelected(int quality, bool isSelected)
        {
            if (!isSelected && this.dataSelected.Count == 0)
                return;

            foreach (var data in this.dataCurrList)
            {
                if (data.isLock)
                    continue;

                if (data.cfgData.Quality == quality)
                {
                    if (isSelected)
                        this.dataSelected.Add(data.id);
                    else
                        this.dataSelected.Remove(data.id);
                }
            }
            this.loopEquips.RefreshCells();
        }

        async UniTaskVoid SendLock(long svid, bool isLock, int index)
        {
            var result = await EquipmentModule.NetCore.CS_lockEquip(svid, isLock);
            if (result.IsFail)
            {
                var item = this.loopEquips.GetTEntity(index);
                item.SetLockState(!isLock, !isLock && this.ud.viewType == UIEquipListType.Lock);
            }
        }
    }
}
